import { isUndefined, isNull, PagedList, PageParams, StringIndexer } from "mmb";
import * as messagepb from "../grpc-client/shared/message_pb";
import * as commonpb from "../grpc-client/service/common_pb";
// import { jsTimestampToPb, pbTimestampToJs } from "./helper";
import GrpcErrCode from "../grpc-client/grpcErrCode";
import {
  getBgsCommonOpSafely,
  getMetadata,
  getOptionsOfLight,
  wrapperGrpcError,
} from "../grpc-client/grpcAdapter";
import { ExpressPlatformInfo, SearchObject } from "./declareTypes";
import SearchTerm from "../bg-enums/searchTerm";

/****************************************************************************************/
/*                                   expressPlatformInfo entity                         */
/****************************************************************************************/

const expressPlatformInfoPbToObject = (
  pb: messagepb.ExpressPlatformInfo
): ExpressPlatformInfo => {
  return {
    id: `${pb.getId()}`,
    name: pb.getName(),
  };
};

/****************************************************************************************/
/*                                   expressPlatformInfo query                          */
/****************************************************************************************/

export const listExpressPlatforms = async (): Promise<
  ExpressPlatformInfo[]
> => {
  const cl = getBgsCommonOpSafely();
  const req = new commonpb.ListExpressPlatformsRequest();

  return new Promise((resolve, reject) => {
    cl.listExpressPlatforms(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        resolve(
          res.getExpressPlatformsList().map(expressPlatformInfoPbToObject)
        );
      }
    );
  });
};

/****************************************************************************************/
/*                                   searchObject entity                                */
/****************************************************************************************/

const searchObjectPbToObject = (pb: messagepb.SearchObject): SearchObject => {
  return {
    id: `${pb.getId()}`,
    name: pb.getName(),
  };
};

/****************************************************************************************/
/*                                   searchObject query                                 */
/****************************************************************************************/

export const listSearchObjectsAsBrand = async (
  brandId: string,
  searchTerm: SearchTerm,
  keyword: string,
  pager: PageParams
): Promise<PagedList<SearchObject>> => {
  const cl = getBgsCommonOpSafely();
  const req = new commonpb.ListSearchObjectsAsBrandRequest();
  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setBrandId(Number(brandId));
  req.setSearchTerm(searchTerm);
  req.setKeyword(keyword);

  return new Promise((resolve, reject) => {
    cl.listSearchObjectsAsBrand(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<SearchObject> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res.getSearchObjectsList().map(searchObjectPbToObject);
        resolve(ret);
      }
    );
  });
};

export const listSearchObjectsAsStore = async (
  storeId: string,
  searchTerm: SearchTerm,
  keyword: string,
  pager: PageParams
): Promise<PagedList<SearchObject>> => {
  const cl = getBgsCommonOpSafely();
  const req = new commonpb.ListSearchObjectsAsStoreRequest();
  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setStoreId(Number(storeId));
  req.setSearchTerm(searchTerm);
  req.setKeyword(keyword);

  return new Promise((resolve, reject) => {
    cl.listSearchObjectsAsStore(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<SearchObject> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res.getSearchObjectsList().map(searchObjectPbToObject);
        resolve(ret);
      }
    );
  });
};

export const listSearchObjectsAsSpokesman = async (
  spokesmanUserId: string,
  searchTerm: SearchTerm,
  keyword: string,
  pager: PageParams
): Promise<PagedList<SearchObject>> => {
  const cl = getBgsCommonOpSafely();
  const req = new commonpb.ListSearchObjectsAsSpokesmanRequest();
  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setSpokesmanUserId(Number(spokesmanUserId));
  req.setSearchTerm(searchTerm);
  req.setKeyword(keyword);
  return new Promise((resolve, reject) => {
    cl.listSearchObjectsAsSpokesman(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<SearchObject> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res.getSearchObjectsList().map(searchObjectPbToObject);
        resolve(ret);
      }
    );
  });
};
